package com.prim.threadpool;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;

public interface ExecutorService extends Executor {

    /**
     * 优雅的关闭线程池
     * 根据之前提交的任务顺序开始shutdown，包括正在等待的任务，但不会接受新的任务。
     * 如果已经shutdown 调用本方法不会有任何影响
     */
    void shutdown();

    /**
     * 立马关闭线程池 粗暴的结束
     * 1. 尝试停止所有正在执行的task
     * 2. 不在执行等待的task，并且返回一个等待执行的task列表
     * 3. 不在接受新的task
     * 这个方法不会等待正在执行的task结束，用awaitTermination方法可以做到
     * 除了尝试正在执行的任务外，这个方法没有任何保证
      * @return
     */
    List<Runnable> shutdownNow();

    /**
     * 如果返回true 表示当前Executor被shutdown
     * @return
     */
    boolean isShutdown();

    /**
     * 如果在shutdown后，所有task都执行完成，返回true
     * 也就是说只有执行了shutdown 或 shutdownNow后，该方法才有可能返回true
     * @return
     */
    boolean isTerminated();

    /**
     * 调用本方法开始阻塞，直到出现如下条件之一：
     * 1. 调用shutdown后所有的task都执行完成
     * 2. 或者达到timeout时间
     * 3. 当前线程终端
     */
    boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException;

    /**
     * 提交一个有返回值的任务，并且返回一个future代表task后面的执行结果
     * future.get() 就是返回task的结果
     */
    <T> Future<T> submit(Callable<T> task);

    /**
     * 提交一个任务，并且自己指定返回结果
     * 任务执行后得到一个future
     * 这个future.get()方法会返回你自己指定的result
     */
    <T> Future<T> submit(Runnable task, T result);

    /**
     * 提交一个任务，任务执行得到一个future，这个future.get()方法返回null
     */
    Future<?> submit(Runnable task);

    /**
     * 执行给定的一些task，当所有任务执行完成后，返回一个future列表
     * 列表里面有执行的状态和结果
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
            throws InterruptedException;

    /**
     * 执行给定的一组task，返回一个列表，列表中有他们的状态和结果
     * 当所有任务执行完成，或者达到超时时间，每个future.isDone()方法都返回true
     * 没有执行完的任务，就被cancelled
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
            throws InterruptedException;

    /**
     * 执行给定一组的tasks,返回执行完成的那个任务的结果，如果任何一个任务成功，其他任务就会被cancelled掉
     * 方法执行时，若传入的集合被修改，返回结果将是undefined
     */
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
            throws InterruptedException, ExecutionException;


    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
}
